SELECT email, full_name, date_added FROM crm_contacts WHERE unsubscribed = 1;
curl -s -X POST https://clarity-crm-api-layer.clarityawarenesscoaching.workers.dev/api/campaigns
-H "Content-Type: application/json"
-d '{"name":"Campaign Name","goal":"What you want to achieve"}'
Save the id returned — you need it for sequences and enrollment.
delay_days is days after the previous step. Step 1 = 0 sends immediately on enrollment. Step 2 = 3 sends 3 days after step 1. Available placeholders: , , , , .###
curl -s -X POST https://clarity-crm-api-layer.clarityawarenesscoaching.workers.dev/api/sequences
-H "Content-Type: application/json"
-d '{
"campaign_id":"CAMPAIGN_ID",
"step_number":1,
"delay_days":0,
"subject":"Your subject",
"body":"
Hi ,
Your message.
<a href="">Unsubscribe
", "from_name":"Lovinia Mak", "from_address":"courses@claritysystems.work" }'curl -s -X POST https://clarity-crm-api-layer.clarityawarenesscoaching.workers.dev/api/enroll
-H "Content-Type: application/json"
-d '{"contact_id":"CONTACT_ID","campaign_id":"CAMPAIGN_ID"}'
SELECT c.email, c.full_name, e.event_type, e.event_time FROM crm_email_events e JOIN crm_contacts c ON c.id = e.contact_id ORDER BY e.event_time DESC LIMIT 20;
Good — pipeline is end-to-end verified. Let me walk you through how to operate it.
How the pipeline works operationally
1. Add contacts
Currently manual via API. From your terminal:
curl -s -X POST https://clarity-crm-api-layer.clarityawarenesscoaching.workers.dev/api/contacts \
-H "Content-Type: application/json" \
-d '{"email":"person@company.com","full_name":"First Last","company":"Company Name"}'
CSV import is not built yet — that's next phase.
2. Create a campaign
curl -s -X POST https://clarity-crm-api-layer.clarityawarenesscoaching.workers.dev/api/campaigns \
-H "Content-Type: application/json" \
-d '{"name":"Campaign Name","goal":"What you want to achieve"}'
Save the id returned — you need it for sequences and enrollment.
3. Write email steps
curl -s -X POST https://clarity-crm-api-layer.clarityawarenesscoaching.workers.dev/api/sequences \
-H "Content-Type: application/json" \
-d '{
"campaign_id":"CAMPAIGN_ID",
"step_number":1,
"delay_days":0,
"subject":"Your subject",
"body":"<p>Hi ,</p><p>Your message.</p><p><a href=\"\">Unsubscribe</a></p>",
"from_name":"Lovinia Mak",
"from_address":"courses@claritysystems.work"
}'
delay_days is days after the previous step. Step 1 = 0 sends immediately on enrollment. Step 2 = 3 sends 3 days after step 1.
Available placeholders: , , , , ``.
4. Enroll a contact
curl -s -X POST https://clarity-crm-api-layer.clarityawarenesscoaching.workers.dev/api/enroll \
-H "Content-Type: application/json" \
-d '{"contact_id":"CONTACT_ID","campaign_id":"CAMPAIGN_ID"}'
Idempotent — safe to run twice, won't double-enroll.
5. Check email status
In D1 Console:
SELECT c.email, c.full_name, e.event_type, e.event_time
FROM crm_email_events e
JOIN crm_contacts c ON c.id = e.contact_id
ORDER BY e.event_time DESC LIMIT 20;
Unsubscribe — what happens
Yes, it updates your database. When someone clicks unsubscribe, the api-layer sets unsubscribed = 1 on that contact in crm_contacts. The sequence runner checks unsubscribed = 0 before every send — that contact will never receive another email from any campaign, permanently.
To check who has unsubscribed:
SELECT email, full_name, date_added FROM crm_contacts WHERE unsubscribed = 1;
What's not built yet that you'll need
| Gap | Impact |
|---|---|
| CSV import | You can't load contacts at scale without it |
| Admin dashboard | All of the above requires terminal curl commands right now |
| Reply ingestion | Replies aren't logged to D1 yet |
CSV import is the most pressing — you shouldn't be adding real contacts one by one. Want to build that next?